home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / sgi.lha / Geomview / data / shaders / hplastic.sl < prev    next >
Text File  |  1993-11-15  |  4KB  |  139 lines

  1. /*
  2.  * Copyright (c) 1990, Geometry Supercomputer Project
  3.  *                     University of Minnesota
  4.  *                     1200 Washington Ave. S
  5.  *                     Minneapolis, MN  55415
  6.  *
  7.  * email address: software@geom.umn.edu
  8.  *
  9.  * This software is copyrighted as noted above.  It may be freely copied,
  10.  * modified, and redistributed, provided that the copyright notice is
  11.  * preserved on all copies.
  12.  *
  13.  * There is no warranty or other guarantee of fitness for this software,
  14.  * it is provided solely "as is".  Bug reports or fixes may be sent
  15.  * to the authors, who may or may not act on them as they desire.
  16.  *
  17.  * You may not include this software in a program or other software product
  18.  * without supplying the source, or without informing the end-user that the
  19.  * source is available for no extra charge.
  20.  *
  21.  * If you modify this software, you should include a notice giving the
  22.  * name of the person performing the modification, the date of modification,
  23.  * and the reason for such modification.
  24.  */
  25.  
  26. /* 
  27.  *  hplastic.sl:    a plastic shader for hyperbolic space
  28.  *  Author:        Charlie Gunn
  29.  *  Description:
  30.  *    The parameters to this shader are the same as the parameters to the regular plastic
  31.  *    shader, but this shader computes angles and distances using the hyperbolic metric.
  32.  *       This metric is defined on homogeneous coordinates (x,y,z,w) and is induced by the 
  33.  *    quadratic form x*x + y*y +z*z - w*w.
  34.  *    This metric is valid on the interior of the unit ball; the isometries of this metric
  35.  *    are projective transformations that preserve the unit sphere and map the interior to 
  36.  *    itself.  These are represented by 4x4 matrices hence can be implemented using the 
  37.  *    regular geometry/viewing pipeline provided by Renderman (and other rendering systems).
  38.  *  Features:
  39.  *    It would be much easier to implement if there were more general datatypes in the 
  40.  *    shading language.  I mean if I could use 4-tuples as points instead of just 3-tuples
  41.  *    the code would be much more compact.  As it is, I have to drag around a "w" coordinate
  42.  *    for each point through all the computations. Ugly.
  43.  */
  44.  
  45. surface
  46. hplastic(
  47.     float Ka    = 1,
  48.         Kd    = 1,
  49.         Ks    = 1,
  50.         roughness = .1;
  51.     color    specularcolor = color (1,1,1);
  52.     )
  53. {
  54.     point    Nh, Ih, M,Lh;
  55.     float    Ihw,Nhw, Mw, Lhw;
  56.     float    a,b,d,ss, nn, mag2,PdotP;
  57.     point    sP;
  58.     color    total;
  59.     uniform float spec;
  60.  
  61.     sP = P;
  62.     PdotP = sP.sP;    
  63.     /* turn it off if outside unit ball */
  64.     if (PdotP >= 1.0)  {
  65.         Ci = 0;
  66.         Oi = 1.0;
  67.         }
  68.  
  69.     else{
  70.     spec = 1.0/roughness;
  71.     Nh = faceforward(normalize(N),I);
  72.     /* make N be "tangent" to P i.e. <P, Nh> = 0*/
  73.     Nhw = sP.Nh;
  74.     nn = sqrt((Nh.Nh) - (Nhw*Nhw));
  75.  
  76.     /* as a difference vector, I has w cord = 0 */
  77.     /* also, we want the L which points at the eye, not the surface */
  78.     Ih = -I;
  79.     b = -((Ih.sP) - 0)/((PdotP) - 1);
  80.     Ih = Ih + b*sP;        /* hyperbolic eye vector is lin comb of I,P */
  81.     Ihw = 0 + b;
  82.     /* normalize this light vector */
  83.     mag2 = sqrt(abs((Ih.Ih) - (Ihw*Ihw)));
  84.     if (mag2 != 0.0) mag2 = 1.0/mag2;
  85.     else mag2 = 1.0;
  86.     Ih = mag2*Ih;
  87.     Ihw = mag2*Ihw;
  88.  
  89.     total = 0;
  90.     illuminance(sP)
  91.     {
  92.     /* compute specular */
  93.     /* first adjust light vector to be tangent at P */
  94.     /* L is also a difference vector, hence its w-cord = 0 */
  95.     b = -((L.sP) - 0)/((PdotP) - 1);
  96.     Lh = L + b*sP;        
  97.     Lhw = 0 + b;
  98.     /* normalize Lh */
  99.     mag2 = sqrt(abs((Lh.Lh) - (Lhw*Lhw)));
  100.     if  (mag2 != 0.0)     mag2 = 1.0/mag2;
  101.     else mag2 = 1.0;
  102.     Lh = mag2*Lh;
  103.     Lhw = mag2*Lhw;
  104.     d = ((Lh.Nh) - (Lhw*Nhw))/nn;
  105.     if (d > 1.0)    /* printf("big d: %f\n",d); */
  106.         d = 1.0;
  107.  
  108.     /* now compute bisector of angle between L and I */
  109.     /* important for Lh, Ih to be unit length */
  110.     M = Ih - Lh;
  111.     Mw = Ihw - Lhw;
  112.     a = -((Ih.M) - (Ihw*Mw))/((Lh.M) - (Lhw*Mw));
  113.     M = Ih + a*Lh;
  114.     Mw = Ihw + a*Lhw;    
  115.     /* detect very small vectors, reject them */
  116.     if (abs(M.M - Mw*Mw) < .0001)    {
  117.         M = Lh;
  118.         Mw = Lhw;
  119.         }
  120.     if (Mw < 0.0)    {
  121.         M = -M;
  122.         Mw = -Mw;
  123.         }
  124.  
  125.     /* compute cos(angle between normal and mid-vector H) */
  126.     ss = ((M.Nh) - (Mw*Nhw))/(sqrt(abs((M.M - Mw*Mw))) * nn);
  127.  
  128.     if (ss < 0.0)    ss = -ss;
  129.     if (ss > 1.0)    ss = 1.0;
  130.  
  131.     total = total + Os * Cs * Cl * (Ka*ambient() + Kd*d);
  132.     total = total + Os * specularcolor * Cl * Ks*pow(ss,spec);
  133.     }
  134.     Ci = total;
  135.     }
  136.     Oi = Os; 
  137. }        
  138.     
  139.